/*
 * Copyright 2012-2014 glodon paas All right reserved. This software is the
 * confidential and proprietary information of glodon paas ("Confidential
 * Information"). You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the license agreement you entered
 * into with glodon paas.
 */
package com.glodon.paas.monitor.web.controller;

import static com.glodon.paas.job.JobConstants.PROPERTY_TASK_CACULATIONBEGIN_TIME;
import static com.glodon.paas.job.JobConstants.PROPERTY_TASK_DOWNLOADBEGIN_TIME;
import static com.glodon.paas.job.JobConstants.PROPERTY_TASK_UPLOADBEGIN_TIME;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.glodon.paas.job.exception.JsonException;
import com.glodon.paas.job.util.JsonUtil;
import com.glodon.paas.monitor.server.biz.domain.TaskEntity;
import com.glodon.paas.monitor.server.biz.service.TaskService;
import com.glodon.paas.monitor.server.dto.MonitorQueryDTO;
import com.glodon.paas.monitor.server.util.DateFormatUtil;
import com.glodon.paas.monitor.web.bean.Messages;
import com.glodon.paas.monitor.web.bean.ModelStatisticsBean;
import com.glodon.paas.util.DateUtil;

/**
 * @author licx 2013-2-1 下午4:57:49
 */
@Controller
public class TaskController extends BaseController {

	private static final Logger	logger	= LoggerFactory.getLogger(JobController.class);

	@Autowired
	private TaskService			taskService;

	@RequestMapping(value = "task")
	public ModelAndView doTaskQueryList(@RequestParam(value = "jobId", required = false) String jobId,
			@RequestParam(value = "fromNum", defaultValue = "0") int fromNum,
			@RequestParam(value = "pageNum", defaultValue = "10") int pageNum,
			@RequestParam(value = "from", required = false) String from,
			@RequestParam(value = "to", required = false) String to,
			@RequestParam(value = "taskTypeChoose", required = false) String taskTypeChoose, ModelMap model)
			throws JsonException, UnsupportedEncodingException {
		if (StringUtils.isBlank(from)) {
			from = DateFormatUtil.getIntervalDate(-30, DateFormatUtil.DAFAULT_DATE_FORMAT);
		}
		if (StringUtils.isBlank(to)) {
			to = DateUtil.formatDate(new Date(), DateUtil.DAFAULT_DATE_FORMAT);
		}
		MonitorQueryDTO taskQueryDTO = buildMonitorQueryDTO(false, null, fromNum, pageNum, null, from, to,
				taskTypeChoose);
		List<TaskEntity> list = taskService.getTaskByMonitorQueryDTO(taskQueryDTO);
		List<Map<String, String>> taskListMap = new ArrayList<Map<String, String>>();
		List<Map<String, String>> taskListMapForJobId = new ArrayList<Map<String, String>>();
		for (TaskEntity item : list) {
			HashMap<String, String> taskMap = new HashMap<String, String>();
			buildTaskMap(item, taskMap);
			taskListMap.add(taskMap);
			if (StringUtils.isNotBlank(jobId)) {
				String jobIdByMap = (String) taskMap.get("jobId");
				if (jobIdByMap.equals(jobId)) {
					taskListMapForJobId.add(taskMap);
				}
			}
		}
		if (null != taskListMapForJobId && !taskListMapForJobId.isEmpty()) {
			model.put("taskListMap", taskListMapForJobId);
		} else {
			model.put("taskListMap", taskListMap);
		}
		return new ModelAndView("task");
	}

	@SuppressWarnings("rawtypes")
	@RequestMapping(value = "/monitor/downLoadTask", method = RequestMethod.GET)
	public void downLoadTask(@RequestParam(value = "jobId", required = false) String jobId,
			@RequestParam(value = "fromNum", defaultValue = "0") int fromNum,
			@RequestParam(value = "pageNum", defaultValue = "20") int pageNum,
			@RequestParam(value = "from", required = false) String from,
			@RequestParam(value = "to", required = false) String to,
			@RequestParam(value = "taskTypeChoose", required = false) String taskTypeChoose,
			HttpServletResponse response) {
		MonitorQueryDTO taskQueryDTO = buildMonitorQueryDTO(false, jobId, fromNum, pageNum, null, from, to,
				taskTypeChoose);
		List<TaskEntity> list = taskService.getTaskByMonitorQueryDTO(taskQueryDTO);
		StringBuffer sb = new StringBuffer();
		String title = null;
		title = Messages.getString("taskTitle");
		sb.append(title).append("\r\n");
		for (TaskEntity entity : list) {
			Map taskInfoMap = new HashMap();
			try {
				taskInfoMap = JsonUtil.jsonToMap(String.valueOf(entity.getTaskInfo()));
			} catch (JsonException e) {
				logger.error("downLoadTask(String, String, HttpServletResponse)", e);
			}
			sb.append("\t" + taskInfoMap.get("jobId") == null ? "" : String.valueOf(taskInfoMap.get("jobId")))
					.append(",").append(String.valueOf(entity.getId())).append(",")
					.append(String.valueOf(entity.getTaskType() == null ? "" : entity.getTaskType()));
			String taskStatus = entity.getStatus() == null ? "" : String.valueOf(entity.getStatus());
			String agentIp = taskInfoMap.get("agent") == null ? "" : taskInfoMap.get("agent").toString();

			String inQuqueTime = "";
			if (entity.getCreateTime() != null) {
				inQuqueTime = DateFormatUtil.format(entity.getCreateTime());
			}
			String downLoadTime = (String) taskInfoMap.get(PROPERTY_TASK_DOWNLOADBEGIN_TIME);
			String computeTime = (String) taskInfoMap.get(PROPERTY_TASK_CACULATIONBEGIN_TIME);
			String uploadTime = (String) taskInfoMap.get(PROPERTY_TASK_UPLOADBEGIN_TIME);
			String endTime = String.valueOf(entity.getEndTime());
			sb.append(",")
					.append(taskStatus)
					.append(",")
					.append(agentIp == null ? "" : String.valueOf(agentIp))
					.append(",\t")
					.append(inQuqueTime == null ? "" : inQuqueTime)
					.append(",\t")
					.append(downLoadTime == null ? "" : downLoadTime)
					.append(",\t")
					.append(computeTime == null ? "" : computeTime)
					.append(",\t")
					.append(uploadTime == null ? "" : uploadTime)
					.append(",\t")
					.append(endTime == null ? "" : endTime)
					.append(taskInfoMap.get("errorMsg") == null ? "" : String.valueOf(taskInfoMap.get("errorMsg"))
							.replaceAll(",", "|")).append("\r\n");
		}
		response.setContentType("application/csv");
		response.setHeader("Content-Disposition", "inline; filename=taskReport.csv");
		PrintWriter out = null;
		try {
			response.setCharacterEncoding("GBK");
			out = new PrintWriter(new OutputStreamWriter(response.getOutputStream(), "GBK"));

		} catch (UnsupportedEncodingException e) {
			logger.error("downLoadTask(String, String, HttpServletResponse)", e);
		} catch (IOException e) {
			logger.error("downLoadTask(String, String, HttpServletResponse)", e);
		}
		out.print(sb.toString());
		out.close();
	}

	@RequestMapping(value = "taskDetail", method = RequestMethod.GET)
	@ResponseBody
	public String getTaskDetail(@RequestParam("taskId") String taskId) throws Exception {
		MonitorQueryDTO taskQueryDTO = buildMonitorQueryDTO(true, taskId, 0, 100, null, null, null, null);
		List<TaskEntity> list = taskService.getTaskByMonitorQueryDTO(taskQueryDTO);
		HashMap<String, String> taskMap = new HashMap<String, String>();
		for (TaskEntity item : list) {
			buildTaskMap(item, taskMap);
		}
		return JsonUtil.mapToJson(taskMap);
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping(value = "taskstatistics", method = RequestMethod.GET)
	public ModelAndView getTaskStatistics(@RequestParam(value = "dateChoose", required = false) String dateChoose,
			ModelMap model) throws Exception {
		cacheTaskStatisticsMap.clear();
		String date = null;
		if (StringUtils.isNotEmpty(dateChoose)) {
			if (dateChoose.equals("0")) {
				date = DateUtil.getIntervalHour(-1);
			} else if (dateChoose.equals("1")) {
				date = DateUtil.getIntervalDate(-1);
			} else if (dateChoose.equals("3")) {
				date = DateUtil.getIntervalDate(-3);
			} else if (dateChoose.equals("7")) {
				date = DateUtil.getIntervalDate(-7);
			} else if (dateChoose.equals("30")) {
				date = DateUtil.getIntervalDate(-30);
			}
		}

		MonitorQueryDTO taskQueryDTO = buildMonitorQueryDTO(true, null, 0, 100, null, date, null, null);
		List<TaskEntity> list = taskService.getTaskByMonitorQueryDTO(taskQueryDTO);
		List<Map<String, String>> mapList = new ArrayList<Map<String, String>>(list.size());
		for (TaskEntity item : list) {
			HashMap<String, String> taskMap = new HashMap<String, String>();
			buildTaskMap(item, taskMap);
			mapList.add(taskMap);
		}
		NumberFormat nf = NumberFormat.getPercentInstance();
		nf.setMinimumFractionDigits(2);
		Map<String, List<Map<String, String>>> groupByTaskTypeMap = buildGroupByTaskTypeMap(mapList);
		List<Map<String, String>> taskStatisticsListMap = new ArrayList<Map<String, String>>(groupByTaskTypeMap.size());
		List<ModelStatisticsBean> taskStatisticsList = buildModelStatisticsList(nf, groupByTaskTypeMap,
				taskStatisticsListMap);
		ModelStatisticsBean taskStatisticsSumDTO = buildModelStatisticsSum(nf, taskStatisticsList);
		Map sumMap = new HashMap();
		if (null != taskStatisticsSumDTO) {
			sumMap = BeanUtils.describe(taskStatisticsSumDTO);
		}
		model.put("sum", sumMap);
		model.put("taskStatisticsListMap", taskStatisticsListMap);
		if (StringUtils.isBlank(dateChoose)) {
			dateChoose = "3";
		}
		model.put("dateChoose", dateChoose);
		return new ModelAndView("taskstatistics");
	}

	@RequestMapping(value = "taskStatisticsDetail", method = RequestMethod.GET)
	@ResponseBody
	public String getTaskStatisticsDetail(@RequestParam("taskType") String taskType) throws Exception {
		Map<String, String> taskStatisticsMap = (Map<String, String>) cacheTaskStatisticsMap.get(taskType);
		if (null == taskStatisticsMap) {
			taskStatisticsMap = new HashMap<String, String>();
		}
		return JsonUtil.mapToJson(taskStatisticsMap);
	}
}
